Relative Displacement using PyMAPDL and PyDPF-Core
This is an example utilizing PyMAPDL to calculate the relative displacement in combination with PyDPF-Core where a field is created and plotted.
The code is divided in two sections. The first is where we make use of MAPDL to calculate the relative displacement. The second part is to use PyDPF-Core, fetch the APDL ARRAY which have stored nodeIds and its corresponding values. Then we can create a scalar field (nodeId|value) and plot it. Procedure:
- In Mechanical, create a Remote Point (this will be the moving Origin) and give it a Pilot Node APDL Name
- Create a body named selection (this will be the geometry scoping) and name it BODY
- In Analysis Settings, Save MAPDL db = Yes
- Save & Solve the analysis. Look at the Directional Deformation Z result. What we see here is that the maximum displacement at t = 3s. is 19.75 mm. In this example model, 10 mm out of 19.75 mm is actually rigid body motion (RBM). We wish to filter the RBM and only include the (strain induced) displacement in Z, which should equal 9.75 mm.
The attached code will make use of the Remote Point as Origin and calculate the relative displacement in Z for each node in the BODY named selection relative to the Origin.
Make sure you correct the rst and db variables with the correct path.
Result: 9.75 mm (relative) displacement Z, as expected.
from ansys.dpf import core as dpf
from ansys.mapdl.core import launch_mapdl
'''PyMAPDL'''
exec_loc = r'C:/Program Files/ANSYS Inc/v242/ansys/bin/winx64/ANSYS242.exe'
mapdl = launch_mapdl(exec_file=exec_loc)
print(mapdl)
# Path to file.rst
rst = r'C:\Data\Support\RELATIVE_DISPLACEMENT\RELATIVE_DISPLACEMENT_files\dp0\SYS\MECH\file.rst'
# Path to file.db
db = r'C:\Data\Support\RELATIVE_DISPLACEMENT\RELATIVE_DISPLACEMENT_files\dp0\SYS\MECH\file.db'
mapdl.resume(fname=db)
mapdl.post1()
mapdl.file(fname=rst)
mapdl.set("LAST")
mapdl.nsel("S", "NODE", "", "ORIGIN")
mapdl.run("NN = NDNEXT(0) ") # NN = REMOTE POINT PILOT NODE
mapdl.run("LOCX=NX(NN)")
mapdl.run("LOCY=NY(NN)")
mapdl.run("LOCZ=NZ(NN) ") # SHOULD STILL EQUAL 0 mm
mapdl.run("DEFZ=UZ(NN)+NZ(NN) ") # SHOULD EQUAL 10 mm
mapdl.allsel()
mapdl.run("CMSEL,S,BODY")
mapdl.nsle()
mapdl.esln()
mapdl.esel("R", "ENAME", "", 185, 186)
mapdl.nsle()
mapdl.run("CM,endNodes,NODE")
mapdl.get("numNodes", "NODE", "", "COUNT")
mapdl.dim("initVecZ", "", "numNodes") # CREATE initVecZ (IS USED IN THE /POST1 COMMANDS LATER)
mapdl.run("BNN=NDNEXT(0)")
with mapdl.non_interactive:
mapdl.run("*DO,ii,1,numNodes")
mapdl.run("initVecZ(ii,1)=NZ(BNN)-LOCZ ") # ___INITIAL VECTOR___
mapdl.run("BNN=NDNEXT(BNN)")
mapdl.run("*ENDDO")
mapdl.run("CMSEL,S,endNodes")
mapdl.get("numNodes", "NODE", "", "COUNT")
mapdl.dim("finalVecZ", "ARRAY", "numNodes","2")
mapdl.run("BNN=NDNEXT(0) ") # BNN = NODE ON BODY/FACE/EDGE,...
with mapdl.non_interactive:
mapdl.run("*DO,ii,1,numNodes")
mapdl.run("finalVecZ(ii,1)=(UZ(BNN)+NZ(BNN)-DEFZ)-initVecZ(ii,1) ") # CALCULATE (FINAL DISTANCE BETWEEN NODE/REMOTE POINT)- (INITIAL DISTANCE BETWEEN NODE/REMOTE POINT)
mapdl.run("finalVecZ(ii,2)= BNN")
mapdl.run("BNN=NDNEXT(BNN)")
mapdl.run("*ENDDO")
'''Extract APDL array to Python!'''
relative_displacement = mapdl.parameters['finalVecZ']
nodeIds = relative_displacement[:,1]
values = relative_displacement[:,0]
'''PyDPF-Core'''
model = dpf.Model(rst)
print('Named selections in model:', model.metadata.available_named_selections)
mesh_scoping = model.metadata.named_selection("BODY")
mesh = model.metadata.meshed_region
# create a field
result_field = dpf.fields_factory.create_scalar_field(
len(nodeIds),
dpf.locations.nodal)
for i in range(0,len(nodeIds)): result_field.append(values[i],int(nodeIds[i]))
result_mesh = dpf.operators.mesh.from_scoping(
scoping=mesh_scoping,
inclusive=1,
mesh=mesh,
nodes_only=False).outputs.mesh()
result_field.meshed_region = result_mesh
import pyvista
result_field.plot(meshed_region=result_mesh)
mapdl.exit()